﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MathNet.Numerics.LinearAlgebra;

namespace NatcarSim {
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class Window1 : Window {
		PathFigure trackPathFigure;
		PathSegmentCollection trackPath;
		LineSegment trackSeg;

		Track mTrack;
		double scale = 1.0;

		public Window1() {
			InitializeComponent();
			mTrack = new Track();
			InitTrackPath();
		}

		private void InitTrackPath() {
			trackPathFigure = new PathFigure();
			trackPathFigure.StartPoint = new Point();
			trackPath = new PathSegmentCollection();
			trackPathFigure.Segments = trackPath;
			PathFigureCollection pfc = new PathFigureCollection();
			pfc.Add(trackPathFigure);
			PathGeometry pg = new PathGeometry();
			pg.Figures = pfc;
			Path myPath = new Path();
			myPath.Stroke = Brushes.Black;
			myPath.StrokeThickness = 1;
			myPath.Data = pg;
			canvas1.Children.Add(myPath);
		}

		private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
			Point pos = e.GetPosition(canvas1);
			if(trackSeg == null) {
				if(trackPath.Count == 0) {
					// track is empty. Create new segment and set as the start point.
					trackPathFigure.StartPoint = pos;
					trackSeg = new LineSegment();
					trackSeg.Point = pos;
					trackPath.Add(trackSeg);
				} else {
					// track exists, let user edit existing track
					trackSeg = new LineSegment(pos, true);
					trackPath.Add(trackSeg);
				}
			} else {
				// continue the existing track
				trackSeg.Point = pos;
				trackSeg = new LineSegment();
				trackSeg.Point = pos;
				trackPath.Add(trackSeg);
			}

			// need to translate pixel coordinates to real coordinates.
			// remember that everything is in cm. Let's map a window
			// area of 500x500px to a real world area of 5000 x 5000 cm^2
			mTrack.AddPoint(pos.X, canvas1.ActualHeight - pos.Y);
		}

		private void canvas1_MouseMove(object sender, MouseEventArgs e) {
			Point mousePos = e.MouseDevice.GetPosition(canvas1);
			this.mousePos.Text = mousePos.ToString();
			if(trackSeg != null) {
				trackSeg.Point = mousePos;
			}
		}

		private void Window_KeyDown(object sender, KeyEventArgs e) {
			if(e.Key == Key.Escape) {			// disengage track edit mode
				if(trackSeg != null) {
					trackPath.Remove(trackSeg);
					trackSeg = null;
				}
			}
		}

		private void loadTrackMenuItem_Click(object sender, RoutedEventArgs e) {
			System.Windows.Forms.OpenFileDialog diag = new System.Windows.Forms.OpenFileDialog();
			diag.CheckFileExists = true;
			if(diag.ShowDialog() != System.Windows.Forms.DialogResult.OK) {
				return;		// abort
			}

			trackPath.Clear();
			mTrack.Load(diag.FileName);
			DrawTrack();
		}

		private void DrawTrack() {
			MathNet.Numerics.LinearAlgebra.Vector start = mTrack.Points[0];
			this.trackPathFigure.StartPoint = new Point(start[0] / scale, start[1] / scale);
			for(int i = 1; i < mTrack.Points.Count; i++) {
				MathNet.Numerics.LinearAlgebra.Vector vec = mTrack.Points[i];
				Point p = new Point(vec[0] / scale, vec[1] / scale);
				LineSegment seg = new LineSegment(p, true);
				trackPath.Add(seg);
			}
		}

		private void saveTrackMenuItem_Click(object sender, RoutedEventArgs e) {
			System.Windows.Forms.SaveFileDialog diag = new System.Windows.Forms.SaveFileDialog();
			diag.AddExtension = true;
			diag.DefaultExt = ".track";
			if(diag.ShowDialog() != System.Windows.Forms.DialogResult.OK) {
				return;
			}

			mTrack.Save(diag.FileName);
		}

		private void dumpTrackMenuItem_Click(object sender, RoutedEventArgs e) {
			mTrack.Dump();
		}

		private void clearTrackMenuItem_Click(object sender, RoutedEventArgs e) {
			mTrack.Clear();
		}

		private void newTrackMenuItem_Click(object sender, RoutedEventArgs e) {

		}
	}
}
